#ifndef __PHYSICSOBJECT_H__
#define __PHYSICSOBJECT_H__
#include "PhysicsVector.h"
#include "PhysicsQuaternion.h"
#include <list>
typedef struct _PhysicsState{
	PhysicsVector position, momentum, angularMomentum;	//orientation,angularMomentum;
	PhysicsQuaternion orientation;
	_PhysicsState();
	_PhysicsState(const _PhysicsState& o);
	_PhysicsState& operator=(const _PhysicsState& o);
	bool operator==(const _PhysicsState& o) const;
	bool operator!=(const _PhysicsState& o) const;
} PhysicsState;
typedef struct _OBoundingBox{
	PhysicsVector position, extents;
	PhysicsQuaternion orientation;
	_OBoundingBox();
	_OBoundingBox(const _OBoundingBox& o);
	_OBoundingBox& operator=(const _OBoundingBox& o);
	bool operator==(const _OBoundingBox& o) const;
	bool operator!=(const _OBoundingBox& o) const;
	const PhysicsVector xAxis();
	const PhysicsVector yAxis();
	const PhysicsVector zAxis();
} OBoundingBox;
class PhysicsObject{
	private:
		float mass, inverseMass;
		PhysicsState intergrate(float t, float dt, bool collision);
		PhysicsState evalDerivative(const PhysicsState& init, float t, float dt, const PhysicsState& d, bool collision);
		bool boundingSphereTest(PhysicsObject* o, float& dt, PhysicsVector& normal);
		friend float positionTest(float t,PhysicsObject* t, PhysicsObject* o);
	public:
		bool gravity;
		PhysicsVector force;
		PhysicsObject();
		virtual ~PhysicsObject() { }
		void render();
		PhysicsVector collision(PhysicsObject* o, float dt, float& t);
		void update(float t, float dt);
		void setMass(float _mass);
		float getMass();
		void setPosition(PhysicsVector x);
		virtual float getBoundingSphere() = 0;
		virtual OBoundingBox getOBoundingBox() = 0;
	protected:
		virtual float inertia() = 0;
		virtual void renderInternal() = 0;
		virtual PhysicsVector collisionResponse(PhysicsObject* o, PhysicsVector v, float t);
		PhysicsState current, previous;
		PhysicsVector Forces(const PhysicsState& s, float t, bool collision);
};
//**** Global exposed Physics Functions ****
namespace PhysicsEngine
{
	list<PhysicsObject*>& getObjects();
	void addObject(PhysicsObject &obj);
}
#endif //__PHYSICSOBJECT_H__
